import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:get/get.dart';
import 'package:intl/intl.dart';
import 'package:squat_easy/generated/assets.dart';
import 'package:squat_easy/se_db/se_db_entity.dart';
import 'package:squat_easy/se_main/se_home/recent_run/se_recent_run_page.dart';
import 'package:squat_easy/se_route.dart';
import 'package:squat_easy/se_standard/se_app_colors.dart';
import 'package:ylm_ui_kit/ylm_ui_kit.dart';

import 'se_home_logic.dart';

class SeHomePage extends StatefulWidget {
  const SeHomePage(this.logic, {Key? key}) : super(key: key);

  final SeHomeLogic logic;

  @override
  State<SeHomePage> createState() => _SeHomePageState();
}

class _SeHomePageState extends State<SeHomePage> with AutomaticKeepAliveClientMixin {
  @override
  Widget build(BuildContext context) {
    super.build(context);
    return const _SeHomePage();
  }

  @override
  bool get wantKeepAlive => true;
}

class _SeHomePage extends GetView<SeHomeLogic> {
  const _SeHomePage();

  @override
  Widget build(BuildContext context) {
    return GetBuilder<SeHomeLogic>(
      builder: (logic) {
        return BaseScaffold(
          hideBackBtn: true,
          titleSpacing: 0,
          appbarBackgroundColor: Colors.transparent,
          resizeToAvoidBottomInset: false,
          child: Stack(
            children: [
              AvoidKeyboard(
                child: SingleChildScrollView(
                  child: Container(
                    decoration: const BoxDecoration(
                      image: DecorationImage(
                        image: AssetImage(Assets.pngHomeBg),
                        fit: BoxFit.cover,
                        alignment: Alignment.topCenter,
                      ),
                    ),
                    padding: EdgeInsets.only(bottom: 20.w),
                    child: Column(
                      children: [
                        ///logo
                        Stack(
                          children: [
                            _buildTopLogo().paddingTop(ScreenUtil().statusBarHeight + 44),
                            _buildArrow().positioned(bottom: 60.w),
                          ],
                        ),

                        ///第一组
                        Container(
                          margin: EdgeInsets.fromLTRB(25.w, 10.w, 25.w, 0),
                          height: 185.w,
                          child: Row(
                            mainAxisAlignment: MainAxisAlignment.spaceBetween,
                            children: [
                              Column(
                                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                                children: [
                                  _buildNextSquat(),
                                  _buildGroup(),
                                ],
                              ),
                              _buildTime(),
                            ],
                          ),
                        ),

                        ///第二组
                        _buildSeconds().padding(top: 20.w, horizontal: 25.w),

                        ///第三组
                        _buildContainer(
                          height: 64.w,
                          radius: 24,
                          gradient: SeAppColors.lightYellowGradient,
                          child: Row(
                            children: [
                              const TextWidget.oneLine(text: 'Continuous', fontSize: 24),
                              Offstage(
                                offstage: !controller.isEdit,
                                child: Container(
                                  alignment: Alignment.center,
                                  child: Container(
                                    width: 64.w,
                                    height: 22.w,
                                    decoration: CommonDecoration.getRadius(all: 5, bg: Colors.black),
                                    alignment: Alignment.center,
                                    child: _buildInput(
                                      controller: controller.daysController,
                                      fontSize: 14,
                                      maxLength: 5,
                                    ),
                                  ),
                                ),
                              ).expanded(),
                              const TextWidget.oneLine(text: 'Days', fontSize: 14),
                            ],
                          ).padding(left: 25.w, right: 25.w),
                        ).padding(top: 20.w, horizontal: 25.w),

                        ///第四组
                        _buildContainer(
                          radius: 24,
                          gradient: SeAppColors.lightBlueGradient,
                          child: Column(
                            crossAxisAlignment: CrossAxisAlignment.start,
                            children: [
                              const TextWidget.oneLine(text: 'Daily training', fontSize: 24).paddingTop(12.w),
                              Opacity(
                                opacity: controller.isEdit ? 1 : 0,
                                child: Container(
                                  constraints: BoxConstraints(
                                    minHeight: 25.w,
                                  ),
                                  decoration: CommonDecoration.getRadius(all: 5, bg: Colors.black),
                                  padding: EdgeInsets.symmetric(horizontal: 10.w),
                                  alignment: Alignment.centerLeft,
                                  child: _buildInput(
                                    controller: controller.dailyTrainingController,
                                    fontSize: 14,
                                    textAlign: TextAlign.left,
                                    contentPadding: EdgeInsets.symmetric(vertical: 8.w),
                                    digitsOnly: false,
                                  ),
                                ).paddingVertical(12.w),
                              ),
                            ],
                          ).padding(left: 25.w, right: 25.w),
                        ).padding(top: 20.w, horizontal: 25.w),

                        ///Recognise
                        if (controller.isEdit) _buildRecogniseBtn().padding(top: 30.w, horizontal: 25.w),

                        ///分割线
                        CommonDivider(height: 2, color: Colors.white, marginLeft: 25.w, marginRight: 25.w)
                            .padding(top: 30.w),

                        ///RecentlyRun
                        RecentlyRunItem(
                          training: controller.recentlyRun,
                          right: ButtonWidget(
                            onTap: () => SeRoute.open(const SeRecentRunPage()),
                            child: GradientText(
                              text: 'View all',
                              style: const TextStyle(fontSize: 14),
                              gradient: SeAppColors.primaryGradient,
                            ),
                          ),
                        ).padding(top: 30.w, horizontal: 25.w),
                      ],
                    ),
                  ),
                ),
              ),
              _buildEditBtn().positioned(left: 25, top: ScreenUtil().statusBarHeight),
            ],
          ),
        );
      },
    );
  }

  Widget _buildInput({
    required TextEditingController controller,
    required double fontSize,
    TextAlign? textAlign,
    int? maxLength,
    EdgeInsets? contentPadding,
    bool digitsOnly = true,
  }) {
    return TextField(
      decoration: InputDecoration(
        border: InputBorder.none,
        isDense: true,
        contentPadding: contentPadding ?? const EdgeInsets.all(0),
      ),
      style: TextStyle(fontSize: fontSize, color: Colors.white),
      textAlign: textAlign ?? TextAlign.center,
      controller: controller,
      keyboardType: digitsOnly ? TextInputType.number : null,
      maxLines: null,
      minLines: 1,
      inputFormatters: [
        if (digitsOnly) FilteringTextInputFormatter.digitsOnly,
        if (maxLength != null) LengthLimitingTextInputFormatter(maxLength),
      ],
      readOnly: !this.controller.isEdit,
    );
  }

  Widget _buildEditBtn() {
    return ButtonWidget.icon(
      ImageWidget.asset(controller.isEdit ? Assets.pngHomeEditDone : Assets.pngHomeEdit, width: 54, height: 54),
      onTap: controller.toggleEdit,
      hasInkWell: false,
    );
  }

  Widget _buildTopLogo() => const FractionallySizedBox(
        widthFactor: 1,
        child: AspectRatio(
          aspectRatio: 0.89,
          child: ImageWidget.asset(Assets.pngHomeTopLogo),
        ),
      );

  Widget _buildArrow() => ImageWidget.asset(Assets.pngHomeArrow, width: 46.w, height: 127.w);

  Widget _buildNextSquat() => Container(
        decoration: CommonDecoration.getRadius(
          gradient: SeAppColors.lightYellowGradient,
          topLeft: 5.w,
          topRight: 20.w,
          bottomLeft: 20.w,
          bottomRight: 5.w,
        ),
        width: 160.w,
        height: 30.w,
        alignment: Alignment.center,
        child: const TextWidget.oneLine(text: 'Next squat', fontSize: 18),
      );

  Widget _buildItemWithOneInput({
    double? width,
    double? height,
    Widget? child,
    int? maxLength,
    required String icon,
    required TextEditingController controller,
  }) {
    return Row(
      children: [
        this.controller.isEdit
            ? Container(
                width: width ?? 80.w,
                height: height ?? 30.w,
                decoration: CommonDecoration.getRadius(all: 5, bg: Colors.black),
                alignment: Alignment.center,
                child: _buildInput(controller: controller, fontSize: 24, maxLength: maxLength),
              )
            : SizedBox(width: width ?? 80.w, height: height ?? 30.w),
        if (child != null) child,
        const Spacer(),
        ImageWidget.asset(icon, width: 22.w, height: 22.w),
      ],
    );
  }

  Widget _buildItemWithTwoInput({
    double? width,
    double? height,
    Widget? child,
    TextAlign? frontTextAlign,
    TextAlign? backTextAlign,
    int? frontLimit,
    int? backLimit,
    double? fontSize,
    required String icon,
    required TextEditingController frontController,
    required TextEditingController backController,
  }) {
    return Row(
      children: [
        controller.isEdit
            ? Container(
                width: width ?? 80.w,
                height: height ?? 30.w,
                decoration: CommonDecoration.getRadius(all: 5, bg: Colors.black),
                alignment: Alignment.center,
                child: Row(
                  children: [
                    _buildInput(
                      controller: frontController,
                      fontSize: fontSize ?? 24,
                      textAlign: frontTextAlign,
                      maxLength: frontLimit,
                    ).expanded(),
                    TextWidget.oneLine(text: 'X', fontSize: fontSize ?? 24, color: Colors.white),
                    _buildInput(
                      controller: backController,
                      fontSize: fontSize ?? 24,
                      textAlign: backTextAlign,
                      maxLength: backLimit,
                    ).expanded(),
                  ],
                ),
              )
            : SizedBox(width: width ?? 80.w, height: height ?? 30.w),
        if (child != null) child,
        const Spacer(),
        ImageWidget.asset(icon, width: 22.w, height: 22.w),
      ],
    );
  }

  Widget _buildGroup() {
    return Container(
      decoration: CommonDecoration.getRadius(gradient: SeAppColors.lightYellowGradient, all: 32),
      width: 160.w,
      height: 142.w,
      alignment: Alignment.center,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          _buildItemWithTwoInput(
            icon: Assets.pngHomeDirectory,
            frontController: controller.groupFrontController,
            backController: controller.groupBackController,
            frontTextAlign: TextAlign.right,
            backTextAlign: TextAlign.left,
            frontLimit: 2,
            backLimit: 2,
            fontSize: 24,
            width: 90.w,
          ).padding(horizontal: 20.w),
          const TextWidget.oneLine(text: 'No. of groups', fontSize: 14),
        ],
      ).paddingVertical(25.w),
    );
  }

  Widget _buildTime() {
    return Container(
      decoration: CommonDecoration.getRadius(gradient: SeAppColors.lightBlueGradient, all: 32),
      width: 156.w,
      alignment: Alignment.center,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          _buildItemWithOneInput(
            icon: Assets.pngHomeEnergy,
            controller: controller.timesController,
            maxLength: 5,
          ).padding(horizontal: 20.w),
          const TextWidget.oneLine(text: 'Completion times', fontSize: 14),
        ],
      ).paddingVertical(25.w),
    );
  }

  Widget _buildSeconds() {
    return Container(
      height: 133.w,
      decoration: CommonDecoration.getRadius(gradient: SeAppColors.lightBlueGradient, all: 32),
      alignment: Alignment.center,
      child: Column(
        mainAxisAlignment: MainAxisAlignment.spaceBetween,
        children: [
          _buildItemWithOneInput(
                  child: const TextWidget.oneLine(text: 's', fontSize: 24).paddingLeft(5.w),
                  icon: Assets.pngHomeTimeBlack,
                  controller: controller.secondsController,
                  maxLength: 5)
              .padding(horizontal: 20.w),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: const [
              TextWidget.oneLine(text: 'Exercise duration', fontSize: 14),
              TextWidget.oneLine(text: 'seconds', fontSize: 14),
            ],
          ).paddingHorizontal(20.w),
        ],
      ).paddingVertical(25.w),
    );
  }

  Widget _buildContainer({
    required Widget child,
    double? height,
    double? radius,
    Gradient? gradient,
  }) {
    return Stack(
      clipBehavior: Clip.none,
      children: [
        Container(
          height: height,
          decoration: CommonDecoration.getRadius(
            gradient: gradient,
            topRight: radius ?? 32.w,
            bottomRight: radius ?? 32.w,
          ),
          alignment: Alignment.centerLeft,
          child: child,
        ),
        Positioned(
          left: 0,
          top: -6.w,
          bottom: -6.w,
          child: ImageWidget.asset(
            Assets.pngHomeLine,
            width: 11.w,
            fit: BoxFit.fill,
          ),
        ),
      ],
    );
  }

  Widget _buildRecogniseBtn() {
    return ButtonWidget(
      onTap: controller.recognise,
      hasInkWell: false,
      child: Stack(
        children: [
          ButtonWidget.text(
            'Recognise',
            fontSize: 18,
            height: 50.w,
            borderRadius: 50.w,
            hasInkWell: false,
            alignment: Alignment.center,
            gradient: SeAppColors.primaryGradient,
          ),
          Container(
            decoration: CommonDecoration.getRadius(bottomLeft: 25.w, topRight: 25.w, bg: Colors.black),
            height: 25.w,
            width: 105.w,
            alignment: Alignment.center,
            child: GradientText(
              text: controller.freeCount <= 0 ? '3 coins' : 'Free X${controller.freeCount}',
              style: const TextStyle(fontSize: 14),
              gradient: SeAppColors.primaryGradient,
            ),
          ).positioned(right: 0, top: 0),
        ],
      ),
    );
  }
}

class RecentlyRunItem extends StatelessWidget {
  const RecentlyRunItem({
    required this.training,
    this.titleFontSize,
    this.right,
    this.gradient,
    this.dateFormat,
    super.key,
  });

  final GroupedTraining training;
  final double? titleFontSize;
  final Widget? right;
  final Gradient? gradient;
  final String? dateFormat;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: CommonDecoration.getShapeDecoration(
        radius: 8.w,
        gradient: gradient ?? SeAppColors.lightBlueGradient,
      ),
      padding: EdgeInsets.symmetric(horizontal: 20.w, vertical: 20.w),
      child: Column(
        children: [
          Row(
            children: [
              _buildTitle().expanded(),
              if (right != null) right!,
            ],
          ),
          if (training.trainings.isNotEmpty)
            ListView.separated(
              padding: EdgeInsets.zero,
              itemCount: training.trainings.length,
              shrinkWrap: true,
              physics: const NeverScrollableScrollPhysics(),
              itemBuilder: (BuildContext context, int index) => RecentlyRunDataItem(training.trainings[index]),
              separatorBuilder: (BuildContext context, int index) => SizedBox(height: 15.w),
            ).paddingTop(20.w),
          if (training.trainings.isNotEmpty) _buildText().paddingTop(15.w),
        ],
      ),
    );
  }

  Widget _buildTitle() {
    String text = '';
    if (dateFormat.notEmpty) {
      try {
        DateTime parsedDate = DateTime.parse(training.groupDate);
        text = DateFormat(dateFormat, 'en_US').format(parsedDate);
      } catch (e) {
        text = training.groupDate;
      }
    } else {
      text = training.groupDate;
    }

    return TextWidget.oneLine(text: text, fontSize: titleFontSize ?? 24);
  }

  Widget _buildText() {
    return Container(
      decoration: CommonDecoration.getRadius(all: 8.w, bg: Colors.black),
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.symmetric(horizontal: 12.w, vertical: 8.w),
      child: TextWidget.moreLine(text: training.trainings.first.dailyTraining, fontSize: 14, color: Colors.white),
    );
  }
}

class RecentlyRunDataItem extends StatelessWidget {
  const RecentlyRunDataItem(this.training, {super.key});

  final Training training;

  @override
  Widget build(BuildContext context) {
    return Container(
      decoration: CommonDecoration.getRadius(all: 8.w, bg: Colors.black),
      alignment: Alignment.centerLeft,
      padding: EdgeInsets.symmetric(vertical: 5.w),
      child: Row(
        children: [
          Expanded(
            flex: 5,
            child: Row(
              children: [
                _buildIcon(),
                _buildGroup().expanded(),
              ],
            ).padding(left: 6.w, right: 12.w),
          ),
          Container(width: 1, height: 15.w, color: Colors.white),
          Expanded(flex: 6, child: _buildNum()),
        ],
      ),
    );
  }

  Widget _buildIcon() => ImageWidget.asset(Assets.pngHomeTimeWhite, width: 19.w);

  Widget _buildGroup() => TextWidget.oneLine(
        text: '${training.groupPrefix}x${training.groupSuffix}',
        fontSize: 14,
        color: Colors.white,
        textAlign: TextAlign.center,
      );

  Widget _buildNum() => TextWidget.oneLine(
        text: '${training.groupPrefix * training.groupSuffix}     Squat',
        fontSize: 14,
        color: Colors.white,
        textAlign: TextAlign.center,
      );
}

class GradientText extends StatelessWidget {
  final String text;
  final TextStyle style;
  final Gradient gradient;

  const GradientText({
    super.key,
    required this.text,
    required this.style,
    required this.gradient,
  });

  @override
  Widget build(BuildContext context) {
    return ShaderMask(
      shaderCallback: (bounds) => gradient.createShader(
        Rect.fromLTWH(0, 0, bounds.width, bounds.height),
      ),
      child: Text(
        text,
        style: style.copyWith(color: Colors.white),
      ),
    );
  }
}
